﻿//#define InitialPath
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

namespace ImageCompressor
{
    public partial class ImageCompressorForm : Form
    {
        public ImageCompressorForm()
        {
            manager = new FilesManager(this);
        }
        /// <summary>
        /// 后台读取图片，并且负责运行
        /// </summary>
        FilesManager manager;
        /// <summary>
        /// 替换原有的Panel作为进度条
        /// </summary>
        NewProgressPanel newProgressPanel;
        protected override void OnLoad(EventArgs e)
        {
            this.newProgressPanel = new NewProgressPanel(new Font("Bahnschrift Condensed", 12F), SystemColors.ControlDark);

            InitializeComponent();
            SetLanguage();

            newProgressPanel.Clone(ProgressPanel);

            ProgressPanel.Visible = false;
            this.Controls.Add(this.newProgressPanel);

            OnSizeChanged(null);

            ZoomInPictureBox.Visible = false;

            PostPictureBox.MouseMove += OnPictureMouseMovePost;
            PreviousPictureBox.MouseMove += OnPictureMouseMovePrevious;
            ZoomInPictureBox.MouseMove += OnZoomMouseMove;
            PostPictureBox.MouseWheel += OnZoomMouseWheelPost;
            PreviousPictureBox.MouseWheel += OnZoomMouseWheelPre;

            MaxWidthPixelTextBox.Leave += MaxWidthPixelTextBox_FocusLeave;
            MaxHeightPixelTextBox.Leave += MaxHeightPixelTextBox_FocusLeave;
            SkipFileSizeTextBox.Leave += SkipFileSizeTextBox_FocusLeave;
            MaxWidthPixelTextBox.KeyDown += TextBox_KeyDown;
            MaxHeightPixelTextBox.KeyDown += TextBox_KeyDown;
            SkipFileSizeTextBox.KeyDown += TextBox_KeyDown;

            ApplySettingsFromForm();
            UpdateDisplayInfo();
            UpdateRunButtonText();
            SetProgressValue(0);

            PathTextBox.DragDrop += Box_DragDrop;
            PathTextBox.DragEnter += Box_DragEnter;

            this.DragDrop += Box_DragDrop;
            this.DragEnter += Box_DragEnter;



#if InitialPath && DEBUG

            //string path = @"C:\Users\wucl12\Downloads\Test\Italy";
            string path = @"D:\Test\temp";
            dragDropFolderPaths.Add(path);
            UpdateDropFilePaths();
            UpdateRunButtonText();
#endif
        }

        /// <summary>
        /// 启动时设置语言
        /// </summary>
        void SetLanguage()
        {
            if(!Localize.IsEN)
            {

                this.PathTextBox.Font = new System.Drawing.Font("等线", 12F);
                this.SizeEstimateLabel.Font = new Font("等线", 12F);
                this.KeepOriginalCheckBox.Font = new Font("等线", 12F);
                this.MaxPixelMultiplyLabel.Font = new Font("等线", 12F);
                this.MaxPixelLimitLabel.Font = new Font("等线", 12F);
                //this.CompressLevelTextLabel.Font = new Font("等线", 15F);
                this.TitleTextLabel.Font = new Font("等线", 12F);
                this.InfoLabel.Font = new Font("等线", 12F);
                this.RunButton.Font = new Font("等线", 12F, FontStyle.Bold);
                this.SubFolderCheckBox.Font = new Font("等线", 12F);
                this.SkipFileSizeLabel.Font = new Font("等线", 12F);
                this.CompressLevelLabel.Font = new Font("等线", 12F);
            }

            this.CompressLevelLabel.Text = Localize.Get("Compress Level (1-10)");
            this.SkipFileSizeLabel.Text = Localize.Get("Skip File Size (KB)");

            this.KeepOriginalCheckBox.Text = Localize.Get("Keep Original (Compress in new folder)");
            this.SubFolderCheckBox.Text = Localize.Get("Include SubFolders");

            this.MaxPixelLimitLabel.Text = Localize.Get("Max Pixel Limit");
            this.TitleTextLabel.Text = Localize.Get("Image Compressor") +" 2023.03.25 by WR";

            this.Text = Localize.Get("Image Compressor");
        }


        #region Resize
        /// <summary>
        /// 点击到左右边界
        /// </summary>
        ClickResize clickResizeHorizen = ClickResize.None;
        /// <summary>
        /// 点击到上下边界
        /// </summary>
        ClickResize clickResizeVertical = ClickResize.None;
        /// <summary>
        /// 记录点击边界值
        /// </summary>
        enum ClickResize
        {
            None,
            Left,
            Right,
            Top,
            Buttom,
        }
        /// <summary>
        /// 鼠标点击位置是移动还是缩放
        /// </summary>
        enum SizeChangeState
        {
            None,
            ChangeSize,
            Move,
        }
        /// <summary>
        /// 记录移动或者缩放状态
        /// </summary>
        SizeChangeState sizeChangeState = SizeChangeState.None;

        /// <summary>
        /// 绘制尺寸时的间距控制常数
        /// </summary>
        const int sizePad = 15;

        /// <summary>
        /// 减少卡顿
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

        /// <summary>
        /// 动态缩放
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            SuspendLayout();
            this.CloseButton.Left = Width - sizePad - CloseButton.Width;
            this.MaxmizeButton.Left = CloseButton.Left - sizePad - MaxmizeButton.Width;
            this.MinimizeButton.Left = MaxmizeButton.Left - sizePad - MinimizeButton.Width;

            this.PathTextBox.Width = Width - sizePad - PathTextBox.Left;

            this.RunButton.Left = Width / 2 + sizePad / 2; 
            this.newProgressPanel.Top = Height - sizePad - newProgressPanel.Height;
            this.newProgressPanel.Left = RunButton.Left;
            this.newProgressPanel.Width = Width - sizePad - RunButton.Left;
            this.ProgressPanel.Location = newProgressPanel.Location;
            this.ProgressPanel.Width = newProgressPanel.Width;


            this.RunButton.Top = this.ProgressPanel.Top - sizePad - RunButton.Height;
            this.RunButton.Width = Width - sizePad - RunButton.Left;
            
            this.InfoLabel.Left = RunButton.Left;
            this.InfoLabel.Top = this.RunButton.Top - sizePad - InfoLabel.Height;

            this.SizeEstimateLabel.Left = this.RunButton.Left;
            this.SizeEstimateLabel.Top = this.InfoLabel.Top - sizePad - this.SizeEstimateLabel.Height;


            this.PostPictureBox.Left = RunButton.Left;
            this.PostPictureBox.Width = this.RunButton.Width;
            this.PostPictureBox.Height = this.SizeEstimateLabel.Top - sizePad - this.PostPictureBox.Top;
            this.PreviousPictureBox.Height = this.PostPictureBox.Height;
            this.PreviousPictureBox.Width = this.PostPictureBox.Left- sizePad - this.PreviousPictureBox.Left;

            this.KeepOriginalCheckBox.Top = ProgressPanel.Top;
            this.SubFolderCheckBox.Top = this.KeepOriginalCheckBox.Top - 10 - this.SubFolderCheckBox.Height;
            
            this.SkipFileSizeTextBox.Top = this.RunButton.Top - this.SkipFileSizeTextBox.Height;
            this.CompressLevelDownButton.Top = this.PostPictureBox.Bottom + sizePad-5;
            this.CompressLevelUpButton.Top = this.CompressLevelDownButton.Top;
            this.CompressLevelTextLabel.Top = this.CompressLevelUpButton.Top + 7;
            this.CompressLevelLabel.Top = this.CompressLevelTextLabel.Bottom - this.CompressLevelLabel.Height-3;
            this.SkipFileSizeTextBox.Top = this.CompressLevelUpButton.Bottom + sizePad-5;
            this.SkipFileSizeLabel.Top = this.SkipFileSizeTextBox.Top+5;

            this.MaxPixelLimitLabel.Top = this.CompressLevelLabel.Top;
            this.MaxPixelMultiplyLabel.Top = this.MaxPixelLimitLabel.Top;
            this.MaxWidthPixelTextBox.Top = this.CompressLevelUpButton.Top + 3;
            this.MaxHeightPixelTextBox.Top = this.MaxWidthPixelTextBox.Top;


            ResumeLayout(false);
            PerformLayout();
        }
        /// <summary>
        /// 点击四边拖拽更改窗口大小的距离距离范围
        /// </summary>
        const float ChangeSizeClickTolerance = 10;
        bool ClickNear(float n1, float n2)
        {
            return Math.Abs(n1 - n2) < ChangeSizeClickTolerance;
        }
        Point moveLocation;
        protected override void OnMouseDown(MouseEventArgs e)
        {

            this.RunButton.Focus();
            sizeChangeState = SizeChangeState.None;
            if(e.Y > ChangeSizeClickTolerance && e.Y < MinimizeButton.Bottom && e.X < MinimizeButton.Left)
            {
                sizeChangeState = SizeChangeState.Move;
                moveLocation = e.Location;
                return;
            }
            if (ClickNear(0, e.X))
            {
                clickResizeHorizen = ClickResize.Left;
                sizeChangeState = SizeChangeState.ChangeSize;
            }
            else if (ClickNear(Bounds.Width, e.X))
            {
                clickResizeHorizen = ClickResize.Right;
                sizeChangeState = SizeChangeState.ChangeSize;
            }
            else clickResizeHorizen = ClickResize.None;

            if (ClickNear(0, e.Y))
            {
                clickResizeVertical = ClickResize.Top;
                sizeChangeState = SizeChangeState.ChangeSize;
            }
            else if (ClickNear(Bounds.Height, e.Y))
            {
                clickResizeVertical = ClickResize.Buttom;
                sizeChangeState = SizeChangeState.ChangeSize;
            }
            else clickResizeVertical = ClickResize.None;
            if (sizeChangeState == SizeChangeState.None)
            {

                base.OnMouseDown(e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            ZoomInPictureBox.Visible = false;

            if (sizeChangeState == SizeChangeState.Move)
            {
                if(this.WindowState != FormWindowState.Normal)
                {
                    this.WindowState = FormWindowState.Normal;
                    moveLocation = new Point(Width / 2, 10);
                }
                else
                {
                    Size size = Bounds.Size;
                    Point location = new Point(Bounds.X + e.X - moveLocation.X, Bounds.Y + e.Y - moveLocation.Y);
                    Bounds = new Rectangle(location, size);
                }
            }
            else if(sizeChangeState == SizeChangeState.ChangeSize)
            {
                this.WindowState = FormWindowState.Normal;
                Point location = Bounds.Location;
                Size size = Bounds.Size;
                bool changed = false;
                if (clickResizeHorizen == ClickResize.Left)
                {
                    location.X = Bounds.X +  e.X;
                    size.Width = Bounds.Width - e.X;
                    changed = true;
                }
                else if (clickResizeHorizen == ClickResize.Right)
                {
                    size.Width = e.X;
                    changed = true;
                }
                if (clickResizeVertical == ClickResize.Top)
                {
                    location.Y = Bounds.Y + e.Y;
                    size.Height = Bounds.Height - e.Y;
                    changed = true;
                }
                else if (clickResizeVertical == ClickResize.Buttom)
                {
                    size.Height = e.Y;
                    changed = true;
                }
                if (changed)
                {
                    Bounds = new Rectangle(location, size);
                }
            }
            else
            {
                bool left = ClickNear(0, e.X);
                bool onHorizon =  left || ClickNear(Bounds.Width, e.X);
                bool top = ClickNear(0, e.Y);
                bool onVertical = top || ClickNear(Bounds.Height, e.Y);
                if (onHorizon && onVertical)
                {
                    if ((left && top) || ((!left) || (!top))) this.Cursor = Cursors.SizeNWSE;
                    else this.Cursor = Cursors.SizeNESW;
                }
                else if (onHorizon)
                {
                    this.Cursor = Cursors.SizeWE;
                }
                else if (onVertical)
                {
                    this.Cursor = Cursors.SizeNS;
                }
                else this.Cursor = Cursors.Default;

                

                base.OnMouseMove(e);
            }
        }


        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (sizeChangeState!= SizeChangeState.None)
            {
                clickResizeHorizen = ClickResize.None;
                clickResizeVertical= ClickResize.None;
                sizeChangeState = SizeChangeState.None;
                OnSizeChanged(null);
            }
            else base.OnMouseUp(e);
        } 
        #endregion

        #region Drag&Drop


        List<string> dragDropFolderPaths = new List<string>();

        /// <summary>
        /// 改变路径Box的消息
        /// </summary>
        /// <param name="messageText"></param>
        private void ChangePathTextBoxMessage(string messageText)
        {
            if (!string.IsNullOrEmpty(messageText))
            {
                PathTextBox.Text = messageText;
                PathTextBox.ForeColor = Color.Gray;
            }
        }

        private void Box_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
            }
            else e.Effect = DragDropEffects.None;
        }

        private void Box_DragDrop(object sender, DragEventArgs e)
        {
            dragDropFolderPaths.Clear();
            Array files = (Array)e.Data.GetData(DataFormats.FileDrop);
            foreach (object file in files)
            {
                FileInfo info = new FileInfo(file.ToString());
                if (info != null && info.Attributes == FileAttributes.Directory)
                {
                    dragDropFolderPaths.Add(info.FullName);
                }
            }
            if (dragDropFolderPaths.Count == 0)
            {
                ChangePathTextBoxMessage(Localize.Get("No Folders Droped"));
                return;
            }
            UpdateDropFilePaths();
            UpdateRunButtonText();

        }
        /// <summary>
        /// 当Drop时更新路径
        /// </summary>
        void UpdateDropFilePaths()
        {
            manager.ReadAllFilePaths(dragDropFolderPaths);
            SetProgressValue(0);
            if (manager.FilesCount == 0)
            {
                MessageBox.Show(Localize.Get("No Images (JPG, PNG, BMP) Found in Folder Droped"), Localize.Get("Warning"));
                PostPictureBox.Image = null;
                PreviousPictureBox.Image = null;
                UpdateDisplayInfo();
                return;
            }
            UpdateDisplayInfo();
            DrawPreviewImg();
            PathTextBox.Lines = dragDropFolderPaths.ToArray();
        }


        #endregion

        #region Zoom Picture

        /// <summary>
        /// 滚轮缩放Zoom框
        /// </summary>
        void OnZoomMouseWheelPre(object sender, MouseEventArgs e)
        {

            if (e.Delta > 0) ZoomFactor.ZoomPercent *= 0.8;
            else ZoomFactor.ZoomPercent *= 1.25;
            DrawZoomInImage(PreviousPictureBox, e);
        }

        void OnZoomMouseWheelPost(object sender, MouseEventArgs e)
        {

            if (e.Delta > 0) ZoomFactor.ZoomPercent *= 0.8;
            else ZoomFactor.ZoomPercent *= 1.25;
            DrawZoomInImage(PostPictureBox, e);
        }

        void OnZoomMouseMove(object sender, MouseEventArgs e)
        {
            ZoomInPictureBox.Location = new Point(ZoomInPictureBox.Left + e.X + 5, ZoomInPictureBox.Top - ZoomInPictureBox.Height  + e.Y - 5);
        }
        
        void OnPictureMouseMovePost(object sender, MouseEventArgs e)
        {
            DrawZoomInImage(PostPictureBox, e);
        }
        void OnPictureMouseMovePrevious(object sender, MouseEventArgs e)
        {
            DrawZoomInImage(PreviousPictureBox, e);
        }
        long CpuTime => DateTime.Now.Ticks / 10000;
        long wait = 0;
        void DrawZoomInImage(PictureBox box, MouseEventArgs e)
        {
            long t = CpuTime;
            if (t - wait > 100) wait = t;
            else return;

            if (PreviousPictureBox.Image == null || PostPictureBox.Image == null)
            {
                ZoomInPictureBox.Visible = false;
                return;
            }
            ZoomInPictureBox.Visible = true;
            ZoomInPictureBox.Location = new Point(box.Left + e.X + 5, box.Top + e.Y - 155);
            ZoomFactor zoomFactor = new ZoomFactor(box.Bounds, e.Location, box.Image.Width, box.Image.Height);
            ZoomInPictureBox.Image = GetZoomImage(zoomFactor);
        }

        Image GetZoomImage(ZoomFactor factor)
        {

            Bitmap newBit = new Bitmap(300, 150);
            Rectangle destRectPre = new Rectangle(0, 0, 150, 150);
            Rectangle destRectPost = new Rectangle(150, 0, 150, 150);
            Graphics graphics = Graphics.FromImage(newBit);
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
            graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
            graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
            graphics.SetClip(destRectPre);
            Rectangle srcRectPre = factor.GetSourceImage(PreviousPictureBox.Image);
            
            graphics.DrawImage(PreviousPictureBox.Image, destRectPre, srcRectPre, GraphicsUnit.Pixel);
            graphics.SetClip(destRectPost);
            Rectangle srcRectPost = factor.GetSourceImage(PostPictureBox.Image);
            graphics.DrawImage(PostPictureBox.Image, destRectPost, srcRectPost, GraphicsUnit.Pixel);
            graphics.Dispose();
            //Debug.WriteLine("srcRectPre = {0}, srcRectPost = {1}", srcRectPre, srcRectPost);
            return newBit;
        }

        #endregion
        
        #region UI Event
        /// <summary>
        /// 防止内部修改文字的时候，调用了TextChange事件
        /// </summary>
        bool internalUpdating = false;
        /// <summary>
        /// 在Drop文件之后，初始化Info显示
        /// </summary>
        private void UpdateDisplayInfo()
        {
            internalUpdating = true;
            CompressLevelTextLabel.Text = manager.CompressLevel.ToString();
            MaxHeightPixelTextBox.Text = manager.MaxHeight.ToString();
            MaxWidthPixelTextBox.Text = manager.MaxWidth.ToString();

            int fileCount = manager.FilesCount;
            if (fileCount > 0)
            {
                newProgressPanel.Text = $"0/{fileCount}";
                newProgressPanel.Refresh();
                manager.SetSkipFileSizeInKB(SkipFileSizeTextBox.Text);
                InfoLabel.Text = string.Format(Localize.Get("Find {0} Imgs , Sum Size = {1}"), manager.FilesCount, manager.GetFileSizeString(manager.PreAllImageSizeinKB));
                
            }
            else
            {
                ChangePathTextBoxMessage(Localize.Get("Drag and Drop Folders Here To Start"));
                newProgressPanel.Text = $"0/0";
                newProgressPanel.Refresh();
                SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate:  ") + "0KB / 0KB";
                InfoLabel.Text = "";
            }
            internalUpdating = false;
        }
        /// <summary>
        /// 将Form的设置运用到后台程序中去
        /// </summary>
        void ApplySettingsFromForm(bool updateWidthHeight = false)
        {
            manager.SetSkipFileSizeInKB(SkipFileSizeTextBox.Text);
            manager.IncludeSubFolders = SubFolderCheckBox.Checked;
            manager.KeepOriginal = KeepOriginalCheckBox.Checked;
            manager.CompressLevel = int.Parse(CompressLevelTextLabel.Text);
            if(updateWidthHeight)
            {
                manager.MaxWidth = int.Parse(MaxWidthPixelTextBox.Text);
                manager.MaxHeight = int.Parse(MaxHeightPixelTextBox.Text);
            }
        }



        /// <summary>
        /// 根据Seed绘制一个压缩后的预览图
        /// </summary>
        void DrawPreviewImg()
        {
            if (!manager.GetRandomIndex(seed, out int index))
            {
                //manager没有文件
                PreviousPictureBox.Image = null;
                PostPictureBox.Image = null;
                SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate:  ") + "0KB / 0KB";
                return;
            }

            var rawImage = manager.GetImageAtIndex(index, out string rawFileSize);
            PreviousPictureBox.Image = rawImage;


            var newImage = manager.GetCompressedImgAtIndex(index, out string newFileSize, out bool skip, out string errorMessage);


            if (skip)
            {
                PostPictureBox.Image = rawImage;
                SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate:  ")+$"{rawFileSize} / {rawFileSize}" + Localize.Get("(Skiped)");
            }
            else
            {
                if (newImage == null)
                {
                    SizeEstimateLabel.Text = errorMessage;
                    PostPictureBox.Image = null;
                    return;
                }
                PostPictureBox.Image = newImage;
                SizeEstimateLabel.Text = Localize.Get("New Image Size Estimate:  ") +$"{newFileSize} / {rawFileSize}";

            }

            ZoomFactor.ZoomPercent = 0.1;
        }


        void SkipFileSizeTextBox_FocusLeave(object sender, EventArgs e)
        {
            if (!int.TryParse(SkipFileSizeTextBox.Text, out _))
                SkipFileSizeTextBox.Text = manager.CurrentSkipFileSizeInKB.ToString();
            ApplySettingsFromForm();
        }

        private void SubFolderCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            ApplySettingsFromForm();
        }

        private void KeepOriginalCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            ApplySettingsFromForm();
        }
        int seed = 0;
        private void PreviousPictureBox_Click(object sender, EventArgs e)
        {
            if (manager.FilesCount > 0)
            {
                seed++;
                DrawPreviewImg();
            }
            else seed = 0;
        }

        private void AfterPictureBox_Click(object sender, EventArgs e)
        {
            if (manager.FilesCount > 0)
            {
                seed--;
                DrawPreviewImg();
            }
            else seed = 0;
        }



        private void CompressLevelTextChanged(bool manuallWidthHeight=false)
        {
            ApplySettingsFromForm(manuallWidthHeight);
            DrawPreviewImg();
            UpdateDisplayInfo();
            
        }

        void MaxHeightPixelTextBox_FocusLeave(object sender, EventArgs e)
        {
            if (internalUpdating) return;
            if (!int.TryParse(MaxHeightPixelTextBox.Text, out _))
            {
                MaxHeightPixelTextBox.Text = manager.MaxHeight.ToString();
            }
            CompressLevelTextChanged(true);
        }


        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Enter)
            {
                this.RunButton.Focus();
            }
        }



        void MaxWidthPixelTextBox_FocusLeave(object sender, EventArgs e)
        {
            if (internalUpdating) return;
            if (!int.TryParse(MaxWidthPixelTextBox.Text, out _))
            {
                MaxWidthPixelTextBox.Text = manager.MaxWidth.ToString();
            }
            CompressLevelTextChanged(true);
        }


        private void CompressLevelDownButton_Click(object sender, EventArgs e)
        {
            if (manager.CompressLevel > 1)
            {
                this.CompressLevelTextLabel.Text = (manager.CompressLevel - 1).ToString();
                CompressLevelTextChanged();
            }
        }

        private void CompressLevelUpButton_Click(object sender, EventArgs e)
        {
            if (manager.CompressLevel < 10)
            {
                this.CompressLevelTextLabel.Text = (manager.CompressLevel + 1).ToString();
                CompressLevelTextChanged();
            }
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            if (manager.State != RunningState.Running)
            {

                this.Close();
                return;
            }
            else
            {
                //发送结束指令
                manager.Stop();
                while (true)
                {
                    if (manager.State != RunningState.Running)
                    {
                        //确保运行结束后才关闭
                        this.Close();
                        return;
                    }
                    else Thread.Sleep(100);
                }
            }
        }

        private void MaxmizeButton_Click(object sender, EventArgs e)
        {
            if (this.WindowState != FormWindowState.Maximized) this.WindowState = FormWindowState.Maximized;
            else this.WindowState = FormWindowState.Normal;
        }

        private void MinimizeButton_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        #endregion

        #region Run

        /// <summary>
        /// 用于内部线程调用
        /// </summary>
        /// <param name="percent"></param>
        public delegate void SetProgressValueDelegate(int percent);
        
        /// <summary>
        /// 设定进度条
        /// </summary>
        /// <param name="value"></param>    
        public void SetProgressValue(int fileCount)
        {
            if (InvokeRequired)
            {
                //从其他线程调用，则在此返回Form线程调用
                SetProgressValueDelegate setProgressValueDelegate = new SetProgressValueDelegate(SetProgressValue);
                this.Invoke(setProgressValueDelegate, fileCount);
            }
            else
            {
                newProgressPanel.ProgressValue =(double)fileCount / manager.FilesCount;
                this.newProgressPanel.Text = $"{fileCount} / {manager.FilesCount}";
                newProgressPanel.Refresh();
            }
        }
        /// <summary>
        /// 根据RunningState更新按钮文字
        /// </summary>
        public void UpdateRunButtonText()
        {
            switch(manager.State)
            {
                case RunningState.NoFile:
                    RunButton.Text = Localize.Get("Waiting for image folders");
                    break;
                case RunningState.Running:
                    RunButton.Text = Localize.Get("Running, Click to Pause");
                    break;
                case RunningState.WaitStop:
                    RunButton.Text = Localize.Get("Running, Wait to Pause");
                    break;
                case RunningState.AllThreadStoped:
                    RunButton.Text = Localize.Get("Paused, Click to Continue");
                    break;
                case RunningState.Finished:
                    RunButton.Text = Localize.Get("Done");
                    break;
                case RunningState.Ready:
                    RunButton.Text = Localize.Get("Ready");
                    break;
                default:
                    RunButton.Text = Localize.Get("Run");
                    break;
            }
        }

        /// <summary>
        /// 点击Run之后运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void RunButton_Click(object sender, EventArgs e)
        {

            if (manager.State == RunningState.Running)
            {
                manager.Stop();
            }
            else if (manager.State == RunningState.Ready || manager.State == RunningState.AllThreadStoped)
            {
                manager.RunAllCompress();
            }
            else //(manager.State == RunningState.Finished)
            {
                RunButton.Text = Localize.Get("Done !!!");
            }

            UpdateRunButtonText();
        }

        /// <summary>
        /// 运行完后显示结束报告
        /// </summary>
        internal void ShowReport()
        {
            if (InvokeRequired)
            {
                //从其他线程调用，则在此返回Form线程调用
                Action ac = new Action(ShowReport);
                this.Invoke(ac);
            }
            else
            {
                CountProgress progress = manager.progress;

                int minutes = (int)progress.stopwatch.Elapsed.TotalMinutes;
                float seconds = progress.stopwatch.Elapsed.Seconds + (progress.stopwatch.Elapsed.Milliseconds / 100) * 0.1f;

                string watchString;
                if (minutes > 0) watchString = string.Format(Localize.Get("{0}min {1}s"),minutes,seconds);
                else watchString = string.Format(Localize.Get("{0}s"),seconds);

                UpdateRunButtonText();
                InfoLabel.Text = string.Format(Localize.Get("Compressed {0},  Skiped {1},  Failed {2},   "), progress.SuccessCount, progress.SkipCount, progress.FailedCount) +
                    string.Format(Localize.Get("Time {0}, Compressed Result {1} / {2}"),watchString,manager.GetFileSizeString(progress.PostSizeKBSum), manager.GetFileSizeString(progress.PreSizeKBSum));
                if (progress.FailedInfos.Count > 0)
                {
                    MessageBox.Show(string.Join("\n", progress.FailedInfos), Localize.Get("Failed Images Info"));
                }
            }
        }


        #endregion


    }


}
